/*
 * Copyright Bruce Liang (ldcsaa@gmail.com)
 *
 * Version	: JessMA 3.5.1
 * Author	: Bruce Liang
 * Website	: http://www.jessma.org
 * Project	: http://www.oschina.net/p/portal-basic
 * Blog		: http://www.cnblogs.com/ldcsaa
 * WeiBo	: http://weibo.com/u/1402935851
 * QQ Group	: 75375912
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package jvlite.util;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import javax.servlet.http.HttpServletRequest;

/** Java Bean 帮助类，执行 Java Bean 反射和内省等相关操作 */
public class BeanUtil {
	/** 简单数据类型集合 */
	public static final Set<Class<?>> SMIPLE_CLASS_SET = new HashSet<Class<?>>(
			18);
	/** 基本类型包装类集合 */
	public static final Set<Class<?>> WRAPPER_CLASS_SET = new HashSet<Class<?>>(
			8);

	private static final String STRING_DELIMITERS = " ,;|\t\n\r\f";
	private static final char ATTR_SEP_CHAR = '.';

	static {
		SMIPLE_CLASS_SET.add(int.class);
		SMIPLE_CLASS_SET.add(long.class);
		SMIPLE_CLASS_SET.add(float.class);
		SMIPLE_CLASS_SET.add(double.class);
		SMIPLE_CLASS_SET.add(byte.class);
		SMIPLE_CLASS_SET.add(char.class);
		SMIPLE_CLASS_SET.add(short.class);
		SMIPLE_CLASS_SET.add(boolean.class);
		SMIPLE_CLASS_SET.add(Integer.class);
		SMIPLE_CLASS_SET.add(Long.class);
		SMIPLE_CLASS_SET.add(Float.class);
		SMIPLE_CLASS_SET.add(Double.class);
		SMIPLE_CLASS_SET.add(Byte.class);
		SMIPLE_CLASS_SET.add(Character.class);
		SMIPLE_CLASS_SET.add(Short.class);
		SMIPLE_CLASS_SET.add(Boolean.class);
		SMIPLE_CLASS_SET.add(String.class);
		SMIPLE_CLASS_SET.add(Date.class);

		WRAPPER_CLASS_SET.add(Integer.class);
		WRAPPER_CLASS_SET.add(Long.class);
		WRAPPER_CLASS_SET.add(Float.class);
		WRAPPER_CLASS_SET.add(Double.class);
		WRAPPER_CLASS_SET.add(Byte.class);
		WRAPPER_CLASS_SET.add(Character.class);
		WRAPPER_CLASS_SET.add(Short.class);
		WRAPPER_CLASS_SET.add(Boolean.class);
	}

	/** 检查是否为非抽象公共实例方法 */
	public static final boolean isInstanceField(Field field) {
		int flag = field.getModifiers();
		return (!Modifier.isStatic(flag));
	}

	/** 检查是否为非抽象公共实例方法 */
	public static final boolean isInstanceNotFinalField(Field field) {
		int flag = field.getModifiers();
		return (!Modifier.isStatic(flag) && !Modifier.isFinal(flag));
	}

	/** 检查是否为非抽象公共实例方法 */
	public static final boolean isPublicInstanceMethod(Method method) {
		int flag = method.getModifiers();
		return (!Modifier.isStatic(flag) && !Modifier.isAbstract(flag) && Modifier
				.isPublic(flag));
	}

	/** 检查是否为公共接口 */
	public static final boolean isPublicInterface(Class<?> clazz) {
		int flag = clazz.getModifiers();
		return (Modifier.isInterface(flag) && Modifier.isPublic(flag));
	}

	/** 检查是否为公共类 */
	public static final boolean isPublicClass(Class<?> clazz) {
		int flag = clazz.getModifiers();
		return (!Modifier.isInterface(flag) && Modifier.isPublic(flag));
	}

	/** 检查是否为非接口非抽象公共类 */
	public static final boolean isPublicNotAbstractClass(Class<?> clazz) {
		int flag = clazz.getModifiers();
		return (!Modifier.isInterface(flag) && !Modifier.isAbstract(flag) && Modifier
				.isPublic(flag));
	}

	/** 检查 clazz 是否为简单数据类型 */
	public final static boolean isSimpleType(Class<?> clazz) {
		return SMIPLE_CLASS_SET.contains(clazz);
	}

	/** 检查 clazz 是否为基础类型包装类 */
	public final static boolean isWrapperType(Class<?> clazz) {
		return WRAPPER_CLASS_SET.contains(clazz);
	}

	/** 检查包装类和基础类型是否匹配 */
	public final static boolean isWrapperAndPrimitiveMatch(
			Class<?> wrapperClazz, Class<?> primitiveClass) {
		if (!primitiveClass.isPrimitive())
			return false;
		if (!isWrapperType(wrapperClazz))
			return false;

		try {
			Field f = wrapperClazz.getDeclaredField("TYPE");
			return f.get(null) == primitiveClass;
		} catch (Exception e) {

		}

		return false;
	}

	/** 检查源类型是否兼容目标类型 */
	public static final boolean isCompatibleType(Class<?> srcClazz,
			Class<?> destClazz) {
		return (destClazz.isAssignableFrom(srcClazz)
				|| isWrapperAndPrimitiveMatch(destClazz, srcClazz) || isWrapperAndPrimitiveMatch(
					srcClazz, destClazz));
	}

	/** 检查源数组的元素类型是否兼容目标数组的元素类型 */
	public static final boolean isCompatibleArray(Class<?> srcClazz,
			Class<?> destClazz) {
		if (srcClazz.isArray() && destClazz.isArray()) {
			Class<?> srcComponentType = srcClazz.getComponentType();
			Class<?> destComponentType = destClazz.getComponentType();

			return isCompatibleType(srcComponentType, destComponentType);
		}

		return false;
	}

	/** 检查属性是否可以联级装配 */
	public static final boolean isCascadableProperty(PropertyDescriptor pd) {
		return (pd != null && getPropertyWriteMethod(pd) != null && isCascadable(pd
				.getPropertyType()));
	}

	/** 检查成员变量是否可以联级装配 */
	public static final boolean isCascadableField(Field f) {
		return (f != null && isInstanceNotFinalField(f) && isCascadable(f
				.getType()));
	}

	/** 检查类是否可以联级装配 */
	public static final boolean isCascadable(Class<?> clazz) {
		return isPublicNotAbstractClass(clazz) && !isSimpleType(clazz)
				&& !clazz.isArray()
				&& !Collection.class.isAssignableFrom(clazz)
				&& !Map.class.isAssignableFrom(clazz);
	}

	@SuppressWarnings("unused")
	private static final <T> Map<String, T> translateKVMap(
			Map<String, T> valueMap, Map<String, String> keyMap) {
		if (keyMap == null || keyMap.isEmpty())
			return valueMap;

		Map<String, T> resultMap = new HashMap<String, T>();
		Set<Map.Entry<String, T>> set = valueMap.entrySet();

		for (Map.Entry<String, T> e : set) {
			String key = e.getKey();
			String name = key;

			if (keyMap.containsKey(key))
				name = keyMap.get(key);

			resultMap.put(name, e.getValue());
		}

		return resultMap;
	}

	@SuppressWarnings("unused")
	private static final <T> Collection<?> parseCollectionParameter(
			Class<? extends Collection<?>> clazz, Class<?> paramClazz, T obj) {
		Collection<Object> col = getRealCollectionClass(clazz);

		if (col != null) {
			Class<?> valueType = obj.getClass();
			String[] value = null;

			if (valueType.isArray())
				value = (String[]) obj;
			else {
				String str = (String) obj;
				StringTokenizer st = new StringTokenizer(str, STRING_DELIMITERS);
				value = new String[st.countTokens()];

				for (int i = 0; st.hasMoreTokens(); i++)
					value[i] = st.nextToken();
			}

			for (int i = 0; i < value.length; i++) {
				String v = value[i];
				Object p = GeneralUtil.str2Object(paramClazz, v);
				col.add(p);
			}
		}

		return col;
	}

	@SuppressWarnings("unchecked")
	private static final Collection<Object> getRealCollectionClass(
			Class<? extends Collection<?>> clazz) {
		Collection<?> col = null;
		Class<?> realClazz = null;

		if (isPublicNotAbstractClass(clazz))
			realClazz = clazz;
		else if (Set.class.isAssignableFrom(clazz))
			realClazz = HashSet.class;
		else if (Collection.class.isAssignableFrom(clazz))
			realClazz = ArrayList.class;

		if (realClazz != null) {
			try {
				col = (Collection<?>) realClazz.newInstance();
			} catch (Exception e) {

			}
		}

		return (Collection<Object>) col;
	}

	/** 通过反射机制调用方法，失败则抛出异常 */
	@SuppressWarnings("unchecked")
	public static final <T> T invokeMethod(Object bean, Method method,
			Object... param) {
		try {
			method.setAccessible(true);
			return (T) method.invoke(bean, param);
		} catch (Exception e) {
			if (e instanceof InvocationTargetException) {
				Exception cause = (Exception) e.getCause();
				if (cause != null)
					e = cause;
			}

			throw new RuntimeException(e);
		}
	}

	/** 通过反射机制获取成员变量值，失败则抛出异常 */
	@SuppressWarnings("unchecked")
	public static final <T> T invokeGetFieldValue(Object bean, Field field) {
		try {
			field.setAccessible(true);
			return (T) field.get(bean);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/** 通过反射机制设置成员变量值，失败则抛出异常 */
	public static final void invokeSetFieldValue(Object bean, Field field,
			Object value) {
		try {
			field.setAccessible(true);
			field.set(bean, value);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/** 通过反射机制设置成员变量值，失败则返回 false，不抛出异常 */
	public static final boolean tryInvokeSetFieldValue(Object bean,
			Field field, Object value) {
		boolean isOK = true;

		try {
			invokeSetFieldValue(bean, field, value);
		} catch (Exception e) {
			isOK = false;
		}

		return isOK;
	}

	@SuppressWarnings("unused")
	private static final <T> Object parseParameter(Class<?> clazz, T obj) {
		Object param = null;
		Class<?> valueType = obj.getClass();

		if (clazz.isArray()) {
			String[] value = null;

			if (valueType.isArray())
				value = (String[]) obj;
			else {
				String str = (String) obj;
				StringTokenizer st = new StringTokenizer(str, STRING_DELIMITERS);
				value = new String[st.countTokens()];

				for (int i = 0; st.hasMoreTokens(); i++)
					value[i] = st.nextToken();
			}

			int length = value.length;
			Class<?> type = clazz.getComponentType();
			param = Array.newInstance(type, length);

			for (int i = 0; i < length; i++) {
				String v = value[i];
				Object p = GeneralUtil.str2Object(type, v);
				Array.set(param, i, p);
			}
		} else {
			String value = null;

			if (valueType.isArray()) {
				String[] array = (String[]) obj;
				if (array.length > 0)
					value = array[0];
			} else
				value = (String) obj;

			param = GeneralUtil.str2Object(clazz, value);
		}

		return param;
	}

	/**
	 * 获取指定类型 Java Bean 的所有属性描述（包括 Object 类除外的所有父类定义的属性）
	 * 
	 * @param startClass
	 *            : Bean 类型
	 * @return 属性名 / 描述对象映射
	 */
	public static final Map<String, PropertyDescriptor> getPropDescMap(
			Class<?> startClass) {
		return getPropDescMap(startClass, Object.class);
	}

	/**
	 * 获取指定类型 Java Bean 的所有属性描述（包括 stopClass 及更高层父类除外的所有父类定义的属性）
	 * 
	 * @param startClass
	 *            : Bean 类型
	 * @param stopClass
	 *            : 截止查找的父类类型
	 * @return 属性名 / 描述对象映射
	 */
	public static final Map<String, PropertyDescriptor> getPropDescMap(
			Class<?> startClass, Class<?> stopClass) {
		Map<String, PropertyDescriptor> map = new HashMap<String, PropertyDescriptor>();

		try {
			BeanInfo info = Introspector.getBeanInfo(startClass, stopClass);
			PropertyDescriptor[] pds = info.getPropertyDescriptors();

			for (PropertyDescriptor pd : pds)
				map.put(pd.getName(), pd);
		} catch (IntrospectionException e) {
			throw new RuntimeException(e);
		}

		return map;
	}

	/**
	 * 获取 Java Bean 的属性
	 * 
	 * @param bean
	 *            : Bean 实例
	 * @return : Bean 属性名 / 值映射
	 */
	public static final Map<String, Object> getProperties(Object bean) {
		Map<String, Object> result = new HashMap<String, Object>();
		Map<String, PropertyDescriptor> pps = getPropDescMap(bean.getClass());
		Set<Map.Entry<String, PropertyDescriptor>> set = pps.entrySet();

		for (Map.Entry<String, PropertyDescriptor> o : set) {
			String key = o.getKey();
			PropertyDescriptor pd = o.getValue();
			Method method = getPropertyReadMethod(pd);

			if (method != null) {
				Object obj = invokeMethod(bean, method);
				result.put(key, obj);
			}
		}

		return result;
	}

	/**
	 * 获取指定类型 Java Bean 的名称为 name 的属性描述对象
	 * 
	 * @param startClass
	 *            : Bean 类型
	 * @param name
	 *            : 属性名称
	 * @return 描述对象映射，找不到属性则返回 null
	 */
	public static final PropertyDescriptor getPropDescByName(
			Class<?> startClass, String name) {
		return getPropDescByName(startClass, Object.class, name);
	}

	/**
	 * 获取指定类型 Java Bean 的名称为 name 的属性描述对象
	 * 
	 * @param startClass
	 *            : Bean 类型
	 * @param stopClass
	 *            : 截止查找的父类类型
	 * @param name
	 *            : 属性名称
	 * @return 描述对象映射，找不到属性则返回 null
	 */
	public static final PropertyDescriptor getPropDescByName(
			Class<?> startClass, Class<?> stopClass, String name) {
		try {
			BeanInfo info = Introspector.getBeanInfo(startClass, stopClass);
			PropertyDescriptor[] pds = info.getPropertyDescriptors();

			for (PropertyDescriptor pd : pds) {
				if (pd.getName().equals(name))
					return pd;
			}
		} catch (IntrospectionException e) {
			throw new RuntimeException(e);
		}

		return null;
	}

	/**
	 * 获取属性的 getter 方法的 {@link Method} 对象
	 * 
	 * @param startClass
	 *            : Bean 类型
	 * @param property
	 *            : 属性名称
	 * @return 描述对象映射，找不到属性则返回 null
	 */
	public static final Method getPropertyReadMethod(Class<?> startClass,
			String property) {
		return getPropertyReadMethod(startClass, null, property);
	}

	/**
	 * 获取属性的 getter 方法的 {@link Method} 对象
	 * 
	 * @param startClass
	 *            : Bean 类型
	 * @param stopClass
	 *            : 截止查找的父类类型
	 * @param property
	 *            : 属性名称
	 * @return 描述对象映射，找不到属性则返回 null
	 */
	public static final Method getPropertyReadMethod(Class<?> startClass,
			Class<?> stopClass, String property) {
		PropertyDescriptor pd = getPropDescByName(startClass, stopClass,
				property);
		return getPropertyReadMethod(pd);
	}

	/**
	 * 获取属性的 getter 方法的 {@link Method} 对象
	 * 
	 * @param pd
	 *            : 属性的 {@link PropertyDescriptor} 描述符
	 * @return {@link Method} 对象，找不到则返回 null
	 */
	public static final Method getPropertyReadMethod(PropertyDescriptor pd) {
		return getPropertyMethod(pd, true);
	}

	/**
	 * 获取属性的 setter 方法的 {@link Method} 对象
	 * 
	 * @param startClass
	 *            : Bean 类型
	 * @param property
	 *            : 属性名称
	 * @return 描述对象映射，找不到属性则返回 null
	 */
	public static final Method getPropertyWriteMethod(Class<?> startClass,
			String property) {
		return getPropertyWriteMethod(startClass, null, property);
	}

	/**
	 * 获取属性的 setter 方法的 {@link Method} 对象
	 * 
	 * @param startClass
	 *            : Bean 类型
	 * @param stopClass
	 *            : 截止查找的父类类型
	 * @param property
	 *            : 属性名称
	 * @return 描述对象映射，找不到属性则返回 null
	 */
	public static final Method getPropertyWriteMethod(Class<?> startClass,
			Class<?> stopClass, String property) {
		PropertyDescriptor pd = getPropDescByName(startClass, stopClass,
				property);
		return getPropertyWriteMethod(pd);
	}

	/**
	 * 获取属性的 setter 方法的 {@link Method} 对象
	 * 
	 * @param pd
	 *            : 属性的 {@link PropertyDescriptor} 描述符
	 * @return {@link Method} 对象，找不到则返回 null
	 */
	public static final Method getPropertyWriteMethod(PropertyDescriptor pd) {
		return getPropertyMethod(pd, false);
	}

	/**
	 * 获取属性的 getter 或 setter 方法的 {@link Method} 对象
	 * 
	 * @param pd
	 *            : 属性的 {@link PropertyDescriptor} 描述符
	 * @param readOrWrite
	 *            : 标识：true -> getter, false -> setter
	 * @return {@link Method} 对象，找不到则返回 null
	 */
	public static final Method getPropertyMethod(PropertyDescriptor pd,
			boolean readOrWrite) {
		if (pd != null) {
			Method method = readOrWrite ? pd.getReadMethod() : pd
					.getWriteMethod();
			if (method != null && isPublicInstanceMethod(method))
				return method;
		}

		return null;
	}

	/**
	 * 获取某个类所有成员变量的 {@link Field} 对象
	 * 
	 * @param clazz
	 *            : 要查找的类
	 * @return : 失败返回空集合
	 */
	public static final Set<Field> getAllFields(Class<?> clazz) {
		return getAllFields(clazz, null);
	}

	/**
	 * 获取某个类所有成员变量的 {@link Field} 对象
	 * 
	 * @param clazz
	 *            : 要查找的类
	 * @param stopClazz
	 *            : 终止查找的类（这个类的成员变量也不被获取）
	 * @return : 失败返回空集合
	 */
	public static final Set<Field> getAllFields(Class<?> clazz,
			Class<?> stopClazz) {
		Set<Field> fields = new HashSet<Field>();

		while (clazz != null && clazz != stopClazz) {
			Field[] fs = clazz.getDeclaredFields();
			Collections.addAll(fields, fs);

			clazz = clazz.getSuperclass();

		}

		return fields;
	}

	/**
	 * 获取某个类所有成员成员变量的 {@link Field} 对象
	 * 
	 * @param clazz
	 *            : 要查找的类
	 * @return : 失败返回空集合
	 */
	public static final Set<Field> getInstanceFields(Class<?> clazz) {
		return getInstanceFields(clazz, null);
	}

	/**
	 * 获取某个类所有成员成员变量的 {@link Field} 对象
	 * 
	 * @param clazz
	 *            : 要查找的类
	 * @param stopClazz
	 *            : 终止查找的类（这个类的成员变量也不被获取）
	 * @return : 失败返回空集合
	 */
	public static final Set<Field> getInstanceFields(Class<?> clazz,
			Class<?> stopClazz) {
		Set<Field> fields = new HashSet<Field>();

		while (clazz != null && clazz != stopClazz) {
			Field[] fs = clazz.getDeclaredFields();
			for (Field f : fs) {
				if (isInstanceField(f))
					fields.add(f);
			}

			clazz = clazz.getSuperclass();
		}

		return fields;
	}

	/**
	 * 获取指定类型 Java Bean 的所有成员成员变量的 {@link Field} 对象（包括 stopClass
	 * 及更高层父类除外的所有父类定义的成员变量） ，该方法会屏蔽父类的同名成员变量
	 * 
	 * @return 成员变量名 / 描述对象映射
	 */
	public static final Map<String, Field> getInstanceFieldMap(Class<?> clazz) {
		return getInstanceFieldMap(clazz, null);
	}

	/**
	 * 获取指定类型 Java Bean 的所有成员变量的 {@link Field} 对象（包括 stopClass
	 * 及更高层父类除外的所有父类定义的成员变量） ，该方法会屏蔽父类的同名成员变量
	 * 
	 * @param clazz
	 *            : Bean 类型
	 * @param stopClazz
	 *            : 截止查找的父类类型
	 * @return 成员变量名 / 描述对象映射
	 */
	public static final Map<String, Field> getInstanceFieldMap(Class<?> clazz,
			Class<?> stopClazz) {
		Map<String, Field> map = new HashMap<String, Field>();

		while (clazz != null && clazz != stopClazz) {
			Field[] fs = clazz.getDeclaredFields();
			for (Field f : fs) {
				String name = f.getName();
				if (isInstanceField(f) && !map.containsKey(name))
					map.put(name, f);
			}

			clazz = clazz.getSuperclass();
		}

		return map;
	}

	/**
	 * 获取 Java Bean 的成员变量值
	 * 
	 * @param bean
	 *            : Bean 实例
	 * @return : Bean 成员变量名 / 值映射
	 */
	public static final Map<String, Object> getFieldValues(Object bean) {
		Map<String, Object> result = new HashMap<String, Object>();
		Map<String, Field> fms = getInstanceFieldMap(bean.getClass());
		Set<Map.Entry<String, Field>> set = fms.entrySet();

		for (Map.Entry<String, Field> o : set) {
			String key = o.getKey();
			Field field = o.getValue();

			if (field != null && isInstanceField(field)) {
				Object obj = invokeGetFieldValue(bean, field);
				result.put(key, obj);
			}
		}

		return result;
	}

	/**
	 * 获取某个类中名称为 name 的成员变量的 {@link Field} 对象
	 * 
	 * @param clazz
	 *            : 要查找的类
	 * @param name
	 *            : 方法名称
	 * @return : 失败返回 null
	 */
	public static final Field getFiledByName(Class<?> clazz, String name) {
		return getFiledByName(clazz, null, name);
	}

	/**
	 * 获取某个类中名称为 name 的成员变量的 {@link Field} 对象
	 * 
	 * @param clazz
	 *            : 要查找的类
	 * @param stopClazz
	 *            : 终止查找的类（这个类的成员变量也不被获取）
	 * @param name
	 *            : 方法名称
	 * @return : 失败返回 null
	 */
	public static final Field getFiledByName(Class<?> clazz,
			Class<?> stopClazz, String name) {
		Field f = null;

		do {
			try {
				f = clazz.getDeclaredField(name);
			} catch (NoSuchFieldException e) {
				clazz = clazz.getSuperclass();
			}
		} while (f == null && clazz != null && clazz != stopClazz);

		return f;
	}

	/**
	 * 获取某个类中名称为 name 的成员成员变量的 {@link Field} 对象
	 * 
	 * @param clazz
	 *            : 要查找的类
	 * @param name
	 *            : 方法名称
	 * @return : 失败返回 null
	 */
	public static final Field getInstanceFiledByName(Class<?> clazz, String name) {
		return getInstanceFiledByName(clazz, null, name);
	}

	/**
	 * 获取某个类中名称为 name 的成员变量的 {@link Field} 对象
	 * 
	 * @param clazz
	 *            : 要查找的类
	 * @param stopClazz
	 *            : 终止查找的类（这个类的成员变量也不被获取）
	 * @param name
	 *            : 方法名称
	 * @return : 失败返回 null
	 */
	public static final Field getInstanceFiledByName(Class<?> clazz,
			Class<?> stopClazz, String name) {
		Field f = null;

		do {
			try {
				Field f2 = clazz.getDeclaredField(name);

				if (isInstanceField(f2)) {
					f = f2;
					break;
				} else
					clazz = clazz.getSuperclass();

			} catch (NoSuchFieldException e) {
				clazz = clazz.getSuperclass();
			}
		} while (clazz != null && clazz != stopClazz);

		return f;
	}

	/**
	 * 获取某个类所有方法的 {@link Method} 对象
	 * 
	 * @param clazz
	 *            : 要查找的类
	 * @return : 失败返回空集合
	 */
	public static final Set<Method> getAllMethods(Class<?> clazz) {
		return getAllMethods(clazz, null);
	}

	/**
	 * 获取某个类所有方法的 {@link Method} 对象
	 * 
	 * @param clazz
	 *            : 要查找的类
	 * @param stopClazz
	 *            : 终止查找的类（这个类的方法也不被获取）
	 * @return : 失败返回空集合
	 */
	public static final Set<Method> getAllMethods(Class<?> clazz,
			Class<?> stopClazz) {
		Set<Method> methods = new HashSet<Method>();

		while (clazz != null && clazz != stopClazz) {
			Method[] m = clazz.getDeclaredMethods();
			Collections.addAll(methods, m);

			clazz = clazz.getSuperclass();

		}

		return methods;
	}

	/**
	 * 获取某个类中名称为 name，参数为 parameterTypes 的方法的 {@link Method} 对象
	 * 
	 * @param clazz
	 *            : 要查找的类
	 * @param name
	 *            : 方法名称
	 * @param parameterTypes
	 *            : 参数类型
	 * @return : 失败返回 null
	 */
	public static final Method getMethodByName(Class<?> clazz, String name,
			Class<?>... parameterTypes) {
		return getMethodByName(clazz, null, name, parameterTypes);
	}

	/**
	 * 获取某个类中名称为 name，参数为 parameterTypes 的方法的 {@link Method} 对象
	 * 
	 * @param clazz
	 *            : 要查找的类
	 * @param stopClazz
	 *            : 终止查找的类（这个类的方法也不被获取）
	 * @param name
	 *            : 方法名称
	 * @param parameterTypes
	 *            : 参数类型
	 * @return : 失败返回 null
	 */
	public static final Method getMethodByName(Class<?> clazz,
			Class<?> stopClazz, String name, Class<?>... parameterTypes) {
		Method m = null;

		do {
			try {
				m = clazz.getDeclaredMethod(name, parameterTypes);
			} catch (NoSuchMethodException e) {
				clazz = clazz.getSuperclass();
			}
		} while (m == null && clazz != null && clazz != stopClazz);

		return m;
	}

	/**
	 * 用 {@linkplain Class#getMethod(String, Class...)} 获取 {@link Method} 对象
	 * 
	 * @param clazz
	 *            : 要查找的类
	 * @param name
	 *            : 方法名称
	 * @param parameterTypes
	 *            : 参数类型
	 * @return : 失败返回 null
	 */
	public static final Method getMethod(Class<?> clazz, String name,
			Class<?>... parameterTypes) {
		Method m = null;

		try {
			m = clazz.getMethod(name, parameterTypes);
		} catch (NoSuchMethodException e) {
		}

		return m;
	}

	public static Map<String, List<String>> parseQueryString(String url)
			throws UnsupportedEncodingException {
		final Map<String, List<String>> query_pairs = new LinkedHashMap<String, List<String>>();
		final String[] pairs = url.split("&");
		for (String pair : pairs) {
			final int idx = pair.indexOf("=");
			final String key = idx > 0 ? URLDecoder.decode(
					pair.substring(0, idx), "utf-8") : pair;
			if (!query_pairs.containsKey(key)) {
				query_pairs.put(key, new LinkedList<String>());
			}
			final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder
					.decode(pair.substring(idx + 1), "utf-8") : null;
			query_pairs.get(key).add(value);
		}
		return query_pairs;
	}

	public static Map<String, Object> getQueryParam()
			throws UnsupportedEncodingException {
		Map<String, String[]> map = new HashMap<String, String[]>();

		String s = "name=SS&marks=99&id=1";
		if (StrUtil.isBlank(s)) {
			return new HashMap<String, Object>();
		}
		try {
			// decode the HTML data by character set UTF-8
			s = URLDecoder.decode(s, "utf-8");
		} catch (UnsupportedEncodingException e) {
			System.err.println("encoding " + "utf-8" + " not support?" + e);
		}

		Map<String, List<String>> query_pairs = parseQueryString(s);

		for (String param : query_pairs.keySet()) {
			List<String> values = query_pairs.get(param);
			String[] values2 = new String[values.size()];
			values2 = values.toArray(values2);
			map.put(param, values2);
		}

		Map<String, Object> params = new HashMap<String, Object>(map.size());
		int len;
		for (Map.Entry<String, String[]> entry : map.entrySet()) {
			len = entry.getValue().length;
			if (len == 1) {
				params.put(entry.getKey(), entry.getValue()[0]);
			} else if (len > 1) {
				params.put(entry.getKey(), entry.getValue());
			}
		}
		return params;
	}

	public static Map<String, Object> getQueryParams(HttpServletRequest request)
			throws UnsupportedEncodingException {
		Map<String, String[]> map = new HashMap<String, String[]>();
		if (request.getMethod().equalsIgnoreCase("POST")) {
			map = request.getParameterMap();
		} else {
			// obtain the request parameter in URL if it is in method GET
			String s = request.getQueryString();
			if (StrUtil.isBlank(s)) {
				return new HashMap<String, Object>();
			}
			try {
				// // decode the HTML data by character set UTF-8
				s = URLDecoder.decode(s, "utf-8");
			} catch (UnsupportedEncodingException e) {
				System.err.println("encoding " + "utf-8" + " not support?" + e);
			}
			Map<String, List<String>> query_pairs = parseQueryString(s);
			for (String param : query_pairs.keySet()) {
				List<String> values = query_pairs.get(param);
				String[] values2 = new String[values.size()];
				values2 = values.toArray(values2);
				map.put(param, values2);
			}
		}

		Map<String, Object> params = new HashMap<String, Object>(map.size());
		Integer len;
		for (Map.Entry<String, String[]> entry : map.entrySet()) {
			len = entry.getValue().length;
			if (len == 1) {
				params.put(entry.getKey(), entry.getValue()[0]);
			} else if (len > 1) {
				params.put(entry.getKey(), entry.getValue());
			}
		}
		return params;
	}

	public static Object toJavaBean(Object javabean, Map<String, Object> m,
			Boolean convertEncode) {
		// use reflect to get methods
		Method[] methods = javabean.getClass().getDeclaredMethods();
		for (Method method : methods) {
			if (method.getName().startsWith("set")) {
				// obtain the parameter types of the method
				Class<?>[] params = method.getParameterTypes();
				String field = method.getName();
				field = field.substring(field.indexOf("set") + 3);
				field = field.toLowerCase();
				// field = field.toLowerCase().charAt(0) + field.substring(1);
				Object value = m.get(field.toString());
				try {
					// convert types for some popular ones
					if (value != null && !"".equals(value)) {
						String pa = params[0].getName().toString();
						if (pa.equals("java.util.Date")) {
							value = new java.util.Date(
									((java.util.Date) value).getTime());
						} else if (pa.equals("java.lang.String")) {
							// value= new
							// java.lang.String(Function.PageToDb(value.toString()));
						} else if (pa.equals("java.lang.Integer")
								|| pa.equals("int")) {
							value = new java.lang.Integer(value.toString());
						} else if (pa.equals("java.lang.Long")) {
							value = new java.lang.Long(value.toString());
						} else if (pa.equals("java.lang.Double")) {
							value = new java.lang.Double(value.toString());
						} else if (pa.equals("java.lang.Float")) {
							value = new java.lang.Float(value.toString());
						} else if (pa.equals("java.lang.Short")) {
							value = new java.lang.Short(value.toString());
						} else if (pa.equals("java.lang.Byte")) {
							value = new java.lang.Byte(value.toString());
						} else if (pa.equals("java.lang.Character")) {
							// value= new java.lang.Character((char) value);
						} else if (pa.equals("java.lang.Boolean")) {
							value = new java.lang.Boolean(value.toString());
						}

						if (value.getClass() == params[0]) {
							method.invoke(javabean, new Object[] { value });
						} else {
							throw new Exception("Cannot set "
									+ field.toString()
									+ ": incompatible types.");
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		return javabean;
	}

	public static Object reqToBean(HttpServletRequest request, Class<?> clazz,
			Boolean isConvert) throws UnsupportedEncodingException,
			InstantiationException, IllegalAccessException {
		Map<String, Object> queryParam = BeanUtil.getQueryParams(request);
		return BeanUtil.toJavaBean(clazz.newInstance(), queryParam, isConvert);
	}

	public static char getAttrSepChar() {
		return ATTR_SEP_CHAR;
	}
}
